use crate::solution::Solution;

impl Solution {
    pub fn alert_names(key_name: Vec<String>, key_time: Vec<String>) -> Vec<String> {
        use std::collections::HashMap;
        let key_time: Vec<_> = key_time
            .into_iter()
            .map(|s| {
                let mut iter = s.split(":");
                let hour: i32 = iter.next().unwrap().parse().unwrap();
                let minute: i32 = iter.next().unwrap().parse().unwrap();
                hour * 60 + minute
            })
            .collect();
        let mut key: Vec<_> = key_name.into_iter().zip(key_time.into_iter()).collect();
        key.sort_unstable_by_key(|k| k.1);
        let mut tab = HashMap::with_capacity(key.len());
        key.into_iter().for_each(|(name, time)| {
            let t = tab.entry(name).or_insert((false, [-3600; 3]));
            t.1[0] = t.1[1];
            t.1[1] = t.1[2];
            t.1[2] = time;
            t.0 |= time - t.1[0] <= 60;
        });
        let mut ans: Vec<_> = tab
            .into_iter()
            .flat_map(|(name, (alerted, _))| if alerted { Some(name) } else { None })
            .collect();
        ans.sort_unstable();
        ans
    }
}


#[cfg(test)]
mod tests {
    use crate::util::string_vec::vec1d_str_to_vec1d_string;
    use super::*;

    #[test]
    fn test_1() {
        let s1 = ["daniel","daniel","daniel","luis","luis","luis","luis"].to_vec();
        let s2 = ["10:00","10:40","11:00","09:00","11:00","13:00","15:00"].to_vec();
        let expected = ["daniel"].to_vec();

        let key_name = vec1d_str_to_vec1d_string(s1);
        let key_time = vec1d_str_to_vec1d_string(s2);

        let output = Solution::alert_names(key_name, key_time);
        // Vec<&str> 和 Vec<String> 也相等？！
        assert_eq!(output, expected);
    }

    #[test]
    fn test_2() {
        // 数组
        let mut s1 = ["alice","alice","alice","bob","bob","bob","bob"];
        // 向量
        let s2 = ["12:01","12:00","18:00","21:00","21:20","21:30","23:00"].to_vec();
        let expected = ["daniel"].to_vec();

        let mut key_name:Vec<String> = Vec::new();
        for key in &mut s1 {
            key_name.push(key.parse().unwrap());
        }
        let key_time = vec1d_str_to_vec1d_string(s2);

        let output = Solution::alert_names(key_name, key_time);
        // Vec<&str> 和 Vec<String> 也相等？！
        assert_eq!(output, expected);
    }
}